package com.example.mycamera;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.nio.ByteBuffer;
import java.util.Arrays;

public class MainActivity extends AppCompatActivity {
    private CameraDevice myCameraDevice;
    private String myCameraId;
    private Surface myTextTureViewSurface;
    private Surface myImageReaderSurface;
    private CameraCaptureSession myCameraCaptureSession;
    private ImageReader myImageReader;
    private ImageView myImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myImageView = findViewById(R.id.imageView);
        TextureView textureView = findViewById(R.id.textureView);
        TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {
                myTextTureViewSurface = new Surface(textureView.getSurfaceTexture());
                open_camera();
            }

            @Override
            public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surfaceTexture) {
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surfaceTexture) {

            }
        };
        textureView.setSurfaceTextureListener(textureListener);
        Button btn = findViewById(R.id.button);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                CaptureRequest.Builder myCaptureRequestBuider = null;
                try {
                    myCaptureRequestBuider = myCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                    myCaptureRequestBuider.addTarget(myImageReaderSurface);
                    myCaptureRequestBuider.set(CaptureRequest.JPEG_ORIENTATION, 90);
                    CaptureRequest myCaptureRequest = myCaptureRequestBuider.build();
                    myCameraCaptureSession.capture(myCaptureRequest, null, null);

                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private void open_camera(){
        myImageReader = ImageReader.newInstance(200, 200, ImageFormat.JPEG, 2);
        myImageReaderSurface = myImageReader.getSurface();
        myImageReader.setOnImageAvailableListener(image_available, null);
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); //获得CameraManager对象

        //检查权限

        if (!ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA)) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 0);
        }
        try {
            if(ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){
                return;
            }
            myCameraId = "0";
            manager.openCamera(myCameraId, camera_state_callback, null);
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }

    ImageReader.OnImageAvailableListener image_available = new ImageReader.OnImageAvailableListener() {
        @Override
        public void onImageAvailable(ImageReader imageReader) {
            Log.i("MengXingYun: ", "Got a Image");
            Image image = myImageReader.acquireLatestImage();
            ByteBuffer byteBuffer = image.getPlanes()[0].getBuffer();
            int length = byteBuffer.remaining();
            byte[] bytes = new byte[length];
            byteBuffer.get(bytes);
            image.close();
            Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, length);
            myImageView.setImageBitmap(bitmap);
        }
    };

    private CameraDevice.StateCallback camera_state_callback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(@NonNull CameraDevice cameraDevice) {
            myCameraDevice = cameraDevice;
            try {
                myCameraDevice.createCaptureSession(Arrays.asList(myTextTureViewSurface, myImageReaderSurface), session_state_callback, null);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onDisconnected(@NonNull CameraDevice cameraDevice) {

        }

        @Override
        public void onError(@NonNull CameraDevice cameraDevice, int i) {

        }
    };

    private CameraCaptureSession.StateCallback session_state_callback = new CameraCaptureSession.StateCallback() {
        @Override
        public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
            myCameraCaptureSession = cameraCaptureSession;
            try {
                CaptureRequest.Builder myCaptureRequestBuider = myCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                myCaptureRequestBuider.addTarget(myTextTureViewSurface);
                CaptureRequest myCaptureRequest = myCaptureRequestBuider.build();
                myCameraCaptureSession.setRepeatingRequest(myCaptureRequest,null, null);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {

        }
    };
}